﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using AForge.Imaging.Filters;

namespace Bildverarbeitung.CGFilter
{
    class FessiAymenFilter : Bildverarbeitung.IFilter
    {
        Boolean
          fast_processing = true,     
          optimal_result = false,    
          trace_result = false;    

        int
           red__1 = 0,
           blue__1 = 0,
           green__1 = 0;

        Color
            clr__;

        Bitmap
            _bmp,
            result;

        Stack<Bitmap>
            stck__;

        /// <summary>
        /// Gets the summerized difference from average of all images.
        /// </summary>
        /// <param name="images">Given images.</param>
        /// <returns>The summerized difference.</returns>
        public Bitmap GetSummerizedDifferencefromAverage(Bitmap[] images)
        {
            if (images.Length < 3) 
            {
                return null;
            }
            else
            {
                if ((images[0].Width < 400) && (images[0].Height < 300))
                    fast_processing = false;

                ResizeBicubic filter = new ResizeBicubic(400, 300);
                Stack<Bitmap> stack_bmp = new Stack<Bitmap>();

                for (int i = 0; i < images.Length; i++)
                {
                    if (fast_processing) stack_bmp.Push(filter.Apply(images[i]));
                    else stack_bmp.Push(images[i]);
                }

                Console.WriteLine("Debut");
                Bitmap result =find_mostly_region_stack(stack_bmp.Pop(),stack_bmp.Pop(),stack_bmp).Pop();
                Console.WriteLine("Fin");
                return result;
            }
        }

        public Stack<Bitmap> find_mostly_region_stack(Bitmap images_1, Bitmap images_2,Stack<Bitmap> stack_bmp)
        {
            if ((stack_bmp.Count == 2) || (stack_bmp.Count == 1)) // basis...
            {
                _bmp = stack_bmp.Pop();

                for (int x = 0; x < images_1.Width; x++)
                {
                    for (int y = 0; y < images_1.Height; y++)
                    {
                        clr__ = _bmp.GetPixel(x, y);

                        int r_1 = Convert.ToInt16(images_1.GetPixel(x, y).R);
                        int r_2 = Convert.ToInt16(images_2.GetPixel(x, y).R);
                        int r_3 = Convert.ToInt16(clr__.R);

                        int g_1 = Convert.ToInt16(images_1.GetPixel(x, y).G);
                        int g_2 = Convert.ToInt16(images_2.GetPixel(x, y).G);
                        int g_3 = Convert.ToInt16(clr__.G);

                        int b_1 = Convert.ToInt16(images_1.GetPixel(x, y).B);
                        int b_2 = Convert.ToInt16(images_2.GetPixel(x, y).B);
                        int b_3 = Convert.ToInt16(clr__.B);

                        red__1 = (r_1 + r_2 + r_3) / 3;

                        if (optimal_result)
                        {
                            red__1 = the_nearest(max(r_1, r_2, r_3),red__1,min(r_1, r_2, r_3));
                        }

                        green__1 = (g_1 + g_2 + g_3) / 3;

                        if (optimal_result)
                        {
                            green__1 = the_nearest(max(g_1, g_2, g_3),green__1,min(g_1, g_2, g_3));
                        }

                        blue__1 = (b_1 + b_2 + b_3) / 3;

                        if (optimal_result)
                        {
                            blue__1 = the_nearest(max(b_1, b_2, b_3),blue__1,min(b_1, b_2, b_3));
                        }

                        result.SetPixel(x, y, Color.FromArgb(red__1, green__1, blue__1));
                    }
                }
                if (trace_result)
                {
                    result.Save("./trace_result_" + System.DateTime.Now.Minute + "_"+ System.DateTime.Now.Millisecond + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
                    Console.WriteLine("++" + stack_bmp.Count);
                }
                stck__.Push(result);
                return stck__;
            }
            else 
            {
                return find_mostly_region_stack(
                    images_1,images_2,find_mostly_region_stack(stack_bmp.Pop(), stack_bmp.Pop(), stack_bmp));
            }
        }

        public int min(int a, int b, int c)
        {
            if (a <= b && a <= c) 
                return a;
            if (b <= a && b <= c) 
                return b;

            else return c;
        }

        public int max(int a, int b, int c)
        {
            if (a >= b && a >= c) 
                return a;
            if (b >= a && b >= c) 
                return b;

            else return c;
        }

        public int the_nearest(int a, int b, int c)
        {
            if ((a - b) <= (b - c)) 
                return a;

            else return b;
        }

        /// <summary>
        /// Return the author´s name
        /// Please use NachnameVorname (without spaces).
        /// </summary>
        /// <returns>author´s name</returns>
        public String GetName()
        {
            return ("FessiAymen");
        }
    }
}
